{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "74fa3159",
   "metadata": {},
   "source": [
    "# 第七节：推理与部署\n",
    "在这一节，我们学习如何将模型部署到手机侧。MindSpore提供了端边云统一的IR，我们只要先将模型转换成mindir格式，就能使用MindSpore Lite再将其转换成端边云对应的格式，并部署到对应端上。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc3fbb37",
   "metadata": {},
   "source": [
    "## 一、转换模型格式\n",
    "使用mindspore中的`export`接口，可以将模型转换成mindir格式，我们直接加载上次训练的模型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "4c65e778",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import mindspore as ms\n",
    "from mindvision.classification.models import LeNet5\n",
    "# 定义参数字典\n",
    "param_dict = ms.load_checkpoint(\"./leNet5/LeNet5-10_1875.ckpt\")\n",
    "# 定义网络\n",
    "net = LeNet5()\n",
    "# 加载参数\n",
    "ms.load_param_into_net(net, param_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f757251",
   "metadata": {},
   "source": [
    "使用export接口转换模型，参数为神经网络，输入tensor，`file_name`指生成的文件名, `file_format`参数选择`MINDIR`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a98e7ac9",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "# 定义输入tensor\n",
    "tensor = ms.Tensor(np.ones([32, 1, 32, 32]), ms.float32)\n",
    "\n",
    "# 使用export接口转换模型\n",
    "ms.export(net, tensor, file_name='LeNet5', file_format=\"MINDIR\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5e9d129a",
   "metadata": {},
   "source": [
    "执行上述语句后，相对路径会多出个“LeNet5.mindir”文件，模型转换成功。\n",
    "\n",
    "输入tensor的类型可以通过访问数据集查看，详情可参考Blog_2数据处理。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8b92226",
   "metadata": {},
   "source": [
    "## 二、部署在手机测\n",
    "### 1、转换模型\n",
    "有了mindir格式的模型，我们需要将其转换成手机侧的ms格式。我们可以使用MindSpore Lite来转换模型，下载与配置可参考[官方文档](https://www.mindspore.cn/lite/docs/zh-CN/r1.8/index.html)。我们选择Windows端，下载文件，解压，将“解压文件路径\\tools\\converter\\lib”添加到环境变量。\n",
    "\n",
    "后面的步骤官方文档写的不是很清楚，我也是各种报错：![](./报错1.png) ![](./报错2.png) ![](./报错3.png)\n",
    "\n",
    "摸索了很久最后在官方交流群中找到正确方法，首先保证环境变量配置正确，然后在`tools\\converter\\converter`路径下执行转换代码：\n",
    "\n",
    "`call converter_lite --fmk=MINDIR --modelFile=model.mindir --outputFile=model`\n",
    "\n",
    "在当前案例中，我们执行：\n",
    "`call converter_lite --fmk=MINDIR --modelFile=LeNet5.mindir --outputFile=LeNet5`\n",
    "\n",
    "注意：此时mindir文件需在`tools\\converter\\converter`路径下。\n",
    "转换成功会返回`CONVERTER RESULT SUCCESS:0`。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f2f1a5e",
   "metadata": {},
   "source": [
    "### 2、配置json文件\n",
    "我们还需要准备json文件，文件内容如下（一定要确保文件内容正确）：![](./json文件格式.png)\n",
    "title为标题，file为转换出的ms模型文件名，label为分类标签。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dfe28c0f",
   "metadata": {},
   "source": [
    "### 3、手机端推理\n",
    "我们需要先下载MindSpore提供的APK，可扫码下载![qr](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r1.8/tutorials/source_zh_cn/beginner/images/app_qr_code.png)\n",
    "将模型文件和json文件推到手机上，打开APP，长按分类模块，进入文件选择，选择刚刚的json文件，提示“`添加自定义模型成功`”，至此我们就可以愉快地使用APP体验训练的模型了。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fdc02cf0",
   "metadata": {},
   "source": [
    "不知道是我的原因还是APP没有优化好的原因，推理过程中经常出现闪退回主界面的情况，这里就暂且展示部分推理照片（正确率还贼低）：\n",
    "![](./手机端推理.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcb191d7",
   "metadata": {},
   "source": [
    "至此，MindSpore入门教程结束，我们将开始进阶学习。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "mindspore",
   "language": "python",
   "name": "mindvision"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
